package opn.srn.common.script;

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;

public abstract class ObjectPool<T> {

	// private static Logger logger = Logger.getLogger(ObjectPool.class);

	private ConcurrentLinkedQueue<T> objectPool = null;
	private AtomicInteger objectPoolSize = null;
	private final int maxCacheSize;

	public ObjectPool() {
		this(16000);
	}

	public ObjectPool(int maxCacheSize) {
		objectPool = new ConcurrentLinkedQueue<T>();
		objectPoolSize = new AtomicInteger(0);
		this.maxCacheSize = maxCacheSize;
	}

	public T getObject() {
		T object = objectPool.poll();
		if (object == null) {
			object = newObject();
		} else {
			objectPoolSize.decrementAndGet();
			object = resetObject(object);
		}
		return object;
	}

	public void release(T object) {
		if (objectPoolSize.intValue() >= maxCacheSize) {
			return;
		}

		boolean inserted = objectPool.offer(object);
		if (inserted) {
			objectPoolSize.incrementAndGet();
		}
	}

	protected abstract T newObject();

	protected abstract T resetObject(T object);
}
